using UnityEngine;
using System.Collections;

public class PlayerController : MonoBehaviour 
{
    public enum eStates { RETRACTED, RETRACTING, EXTENDING, GRABBING };
    public eStates state;
    public float verticalSpeed; // how fast you can drop and ascend
    public GameObject heldObject;
    public float defaultHeight;
    private Vector3 raycastResult;  // only used internally
    private bool inputRestricted;

    private GameObject dropShadow;

    // State property
    public eStates State
    {
        get { return state; }
        set
        {
            Debug.Log("Entering the " + value.ToString() + " state");

            switch (value)
            {
                case eStates.RETRACTED:
                    inputRestricted = false;
                    Debug.Log("Input freed.");
                break;
                case eStates.RETRACTING:
                    GetComponentInChildren<Animation>().Play("Crane_Retracting");
                break;
                case eStates.EXTENDING:
                   GetComponentInChildren<Animation>().Play("Crane_Extending");
                    inputRestricted = true;
                    Debug.Log("Input restricted.");
                break;
                default:
                {
                    // stop any other animations that may be playing
                    if (GetComponentInChildren<Animation>().isPlaying)
                    {
                        GetComponentInChildren<Animation>().Stop();
                    }
                }
                break;

            };

            state = value;
        }
    }
 


	// Use this for initialization
	void Start()
    {
        state = eStates.RETRACTED;

        dropShadow = GameObject.Find("DropShadow");
        dropShadow.transform.position = new Vector3(0, 10.0f, 0); // start way up

        Debug.Log("Dropshadow set: " + dropShadow.gameObject.name);

       // if (defaultHeight <= 0.0f)
       //     defaultHeight = 5.0f;

	}
	
	// Update is called once per frame
	void Update() 
    {
        if (Time.timeScale <= 0)
            return;

        // activate drop shadow if we're carrying && not in extending state
        if (state == eStates.RETRACTED && heldObject != null)
            dropShadow.transform.position = new Vector3(transform.position.x, 0.45f, transform.position.z);
        else
            dropShadow.transform.position = new Vector3(transform.position.x, 100.0f, transform.position.z);


        if (!inputRestricted)
        {
            // Movement

            // Raycast from camera to point clicked
            // directly set the player's X and Z to the point's X and Z
            // Y should be set to defaultHeight.

            Vector3 vMouseClick = Input.mousePosition;
            Ray ray = Camera.main.ScreenPointToRay(vMouseClick);

            RaycastHit hitInfo = new RaycastHit();
            int nFloorLayer = 1 << LayerMask.NameToLayer("Floor");
			int nInaccessibleLayer = 1 << LayerMask.NameToLayer("Inaccessible");
            if (Physics.Raycast(ray, out hitInfo, Mathf.Infinity, nFloorLayer) 
				&& !Physics.Raycast(ray, out hitInfo, Mathf.Infinity, nInaccessibleLayer) )
            {
                raycastResult = hitInfo.point;
                transform.position = new Vector3(hitInfo.point.x, defaultHeight, hitInfo.point.z);
            }



            if (Input.GetButton("Fire1"))
            {
                // our drop shadow should be doing the valid drop spot checking for us.
                if (heldObject == null || (heldObject != null && dropShadow.GetComponent<DropShadow>().IsValidPlacement))
                {
                    // we're fine
                    State = eStates.EXTENDING;
                }
                
            }

        }
 
        switch (state)
        {
            case eStates.RETRACTING:
                {
                    // when animation done, go to retracted
                    if (!GetComponentInChildren<Animation>().IsPlaying("Crane_Retracting"))
                    {
                        State = eStates.RETRACTED;
                        // Set drop shadow to active
                        //dropShadow.active = true;
                    }                
                }
                break;
            case eStates.RETRACTED:
                {
                    // Essentially an idle/moving state
                }
                break;
            case eStates.EXTENDING:
                {
                    if (heldObject != null && heldObject.gameObject.GetComponent<Carryable>().Grounded)
                    {
                        // Let go
                        heldObject.transform.parent = null;
                        heldObject = null;
                    }

                    // when animation done, go to extended
                    if (!GetComponentInChildren<Animation>().IsPlaying("Crane_Extending"))
                    {
                        State = eStates.GRABBING;
                    }
                }
                break;
            case eStates.GRABBING:
                {
                    // once grab animation is done, check for collision
                    // if a carryable object, grab it and child it to me (inside collider handler)
                    // go to retracting

                    if (!GetComponentInChildren<Animation>().IsPlaying("Crane_Grabbing"))
                    {
                        // set trigger to active
                        State = eStates.RETRACTING;
                    }


                }
                break;
        };
	}

    public bool isCarrying()
    {
        return (heldObject == null);
    }

    //void OnTriggerEnter(Collider other)
    //{
    //    Debug.Log("Player Collide");

    //    switch (state)
    //    {
    //        case eStates.EXTENDING:
    //            {
    //                // If we're landing on something we can't pick up, immediately retract
    //                if (other.gameObject.GetComponent<Carryable>() == null)
    //                {
    //                    Debug.Log("Can't pick up " + other.gameObject.name + ": retracting");
    //                    State = eStates.RETRACTING;
    //                }
    //                else
    //                {
    //                    // is it grounded?
    //                    if (other.gameObject.GetComponent<Carryable>().Grounded)
    //                    {
    //                    }

    //                    heldObject = other.gameObject;
    //                    Debug.Log("Picking up " + heldObject.name);
    //                    other.gameObject.transform.parent = gameObject.transform;
    //                }

    //            }
    //            break;

    //    };

    //}


    void OnDrawGizmos()
    {
        Gizmos.DrawWireSphere(raycastResult, 0.1f);
    }
}
